package com.ease.framework.gef4p.figures.impl {

  import com.ease.util.CursorManagerExt;
  import com.ease.util.collections.HashMap;
  import com.ease.util.collections.Map;
  import com.ease.component.controls.HandlesMouseCursors;
  import com.ease.framework.flex.controls.Handle;
  import com.ease.framework.flex.controls.HandleLocationType;
  import com.ease.framework.gef.ui.ISelection;
  import com.ease.framework.gef4p.figures.IFigureResizable;

  import flash.events.KeyboardEvent;
  import flash.events.MouseEvent;
  import flash.geom.Point;
  import flash.ui.Keyboard;

  import mx.containers.Canvas;
  import mx.core.UIComponent;

  public class FigureWithHandles extends Canvas implements ISelection, IFigureResizable {

    private var allowRotate:Boolean = false;

    [Inspectable(defaultValue=true)]
    private var _allowRisize:Boolean = true;

    protected var handleOptions:Array = null;
    protected var handles:Array = null;
    private var _handleMaps:Map = new HashMap();

    /**
    * 用于记录当前对象是否已经被选中.
    **/
    [Inspectable(defaultValue=false)]
    private var _isSelected:Boolean = false;

    public function FigureWithHandles() {
      super();
      this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);

      focusEnabled = true;
    }

    protected function onKeyDown(event:KeyboardEvent):void {
      if(!this.isSelected) return;

      switch(event.keyCode) {
        case Keyboard.UP:   handleUpPress(event.shiftKey); break;
        case Keyboard.DOWN: handleDownPress(event.shiftKey); break;
        case Keyboard.LEFT: handleLeftPress(event.shiftKey); break;
        case Keyboard.RIGHT:handleRightPress(event.shiftKey); break;
        case Keyboard.SPACE:handleSpace(); break;
      }
    }

    protected function handleSpace():void {
    }

    protected function handleUpPress(shiftKeyDown:Boolean):void {
         var pos:Point = new Point(x, y);

         if( shiftKeyDown ) {
            pos.y --;
      }
         else {
            pos.y=pos.y - 10;
      }
         y = pos.y;
         x = pos.x;
    }

    protected function handleDownPress(shiftKeyDown:Boolean):void {
      var size:Point = new Point(width, height);
      var pos:Point = new Point(x, y);

      if(shiftKeyDown) {
        size.y ++;
      }
      else {
        pos.y++;
      }
      y = pos.y;
      x = pos.x;
      width = size.x;
      height = size.y;
    }

    protected function handleLeftPress(shiftKeyDown:Boolean):void {
      var size:Point = new Point(width, height);
      var pos:Point = new Point(x, y );

      if(shiftKeyDown) {
        size.x --;
      }
      else {
        pos.x --;
      }
      y = pos.y;
      x = pos.x;
      width = size.x;
      height = size.y;
    }
    protected function handleRightPress(shiftKeyDown:Boolean):void {
      var size:Point = new Point(width,height);
      var pos:Point = new Point(x, y );

      if(shiftKeyDown) {
        size.x ++;
      }
      else {
        pos.x++;
      }
      y = pos.y;
      x = pos.x;
      width = size.x;
      height = size.y;
    }

    public function select():void {
      showHandles(true);
      _isSelected = true;
      setFocus();
      updateDisplayList(width,height);
    }

    public function deselect():void {
      drawFocus(false);
      showHandles(false);
      _isSelected = false;

      updateDisplayList(width,height);
    }

    public function get isSelected():Boolean{
      return _isSelected;
    }

    public function get allowRisize():Boolean{
      return _allowRisize;
    }

    public function set allowRisize(value:Boolean):void{
      _allowRisize = value;
    }

    protected function showHandles(visible:Boolean):void {
      if(handles==null) {
        handles = createHandles();
      }

      for each (var u:UIComponent in handles) {
        u.setVisible(visible);
      }
    }

    public function getHandleByType(type:int):Handle {
      if(handles==null) createHandles();
      return _handleMaps.getObject(type) as Handle;
    }

    public function putHandle(handle:Handle):void{
      _handleMaps.put(handle.type,handle);
    }

    public function getHandles():Array{
      if(handles == null) createHandles();
      return handles;
    }

    protected function onMouseOver(event: MouseEvent):void{
      if(!this.isSelected) {
        return;
      }
      if( this.allowRisize ) {
        if(!event.buttonDown) {
          setMouseCursor(event.stageX,event.stageY);
        }
      }
    }

    protected function clearHandles():void{
      _handleMaps.clear();

      if(handles != null) {
        for each (var handle:Handle in handles) {
          super.removeChild(handle);
        }
        handles = null;
      }
    }

    protected function setMouseCursor(x:Number, y:Number):void {
      for each (var handle:Handle in handles ) {
        if(handle.hitTestPoint(x, y)) {
          if(CursorManagerExt.currentHandleCursorID > 0) {
            CursorManagerExt.removeCursor(CursorManagerExt.currentHandleCursorID);
               }
          CursorManagerExt.setHandleCursor(HandlesMouseCursors.getCursor(handle.getCursorName()), 2, -5, -8);
          return;
        }
      }
    }

    /**
     * On startup, creates the various handles that the user can interact with.
     **/
    protected function createHandles():Array {
      var handles:Array = new Array();

       var defaultHandleOptions:Array = [
         {resizeUp:true, resizeDown:false, resizeRight:false, resizeLeft:false, style:{top:-0.7, horizontalCenter:0 }, type:HandleLocationType.LOCATION_TOP },
                {resizeUp:true, resizeDown:false, resizeRight:false, resizeLeft:true,style:{top:-0.7, left:-0.5}, type:HandleLocationType.LOCATION_LEFT_TOP },
                {resizeUp:true, resizeDown:false, resizeRight:true, resizeLeft:false,style:{top:-0.7, right:-3}, type:HandleLocationType.LOCATION_RIGHT_TOP },
                {resizeUp:false, resizeDown:true, resizeRight:false, resizeLeft:false,style:{bottom:-3, horizontalCenter:0 }, type:HandleLocationType.LOCATION_BOTTOM },
                {resizeUp:false, resizeDown:true, resizeRight:false, resizeLeft:true,style:{bottom:-3, left:-0.5 }, type:HandleLocationType.LOCATION_LEFT_BOTTOM },
                {resizeUp:false, resizeDown:true, resizeRight:true, resizeLeft:false,style:{bottom:-3, right:-3}, type:HandleLocationType.LOCATION_RIGHT_BOTTOM },
                {resizeUp:false, resizeDown:false, resizeRight:false, resizeLeft:true,style:{verticalCenter:0, left:-0.5}, type:HandleLocationType.LOCATION_LEFT },
                {resizeUp:false, resizeDown:false, resizeRight:true, resizeLeft:false,style:{verticalCenter:0, right:-3}, type:HandleLocationType.LOCATION_RIGHT }
      ];

      var handleOptions:Array = handleOptions != null ? handleOptions : defaultHandleOptions;

      for each (var option:Object in handleOptions) {
﻿            var isCorner:Boolean = 2 == (( option.resizeUp ? 1 : 0 ) + ( option.resizeDown ? 1 : 0 ) + ( option.resizeLeft ? 1 : 0 ) + ( option.resizeRight ? 1 : 0 ) ); // Corners can resize in 2 directions.

        var handle:Handle = new Handle();

        handle.resizeDown = option.resizeDown;
        handle.resizeLeft = option.resizeLeft;
        handle.resizeRight = option.resizeRight;
        handle.resizeUp = option.resizeUp;
        handle.visible = false;
        handle.type = option.type;
        handle.draw();

         for (var prop:String in option.style) {
          switch(prop) {
            case "top":
            case "bottom":
               handle.setStyle(prop, option.style[prop] * handle.height);
               break;
             default:
               handle.setStyle(prop, option.style[prop] * handle.width);
               break;
           }
          }

        super.addChild(handle);
        handles.push(handle);

        _handleMaps.put(handle.type,handle);
      }
      return handles;
    }
  }
}
